/*

  I2C interface

*/

#include <io.h>

#include "i2c.h"

#include "../timing/timing.h"

//XA (10 bit address) should be 0, I2CWORD (2 byte receive mode) = 0, I2CRM=0
//SWRST = 1, I2CEN =0, I2CSTT = 1, I2CSTP = 0, I2CRM = 0
//flags to watch for pg 15-18 slau49 NACKIFG,RXRDYIFG, TXRDYIFG pg 15-30 for register instructions

void square(){ /* output in case of interupt cancelling transmission due to no ack or similar*/
int i;

  P1DIR=255; //Set Port 3 as an output port

  while (1) { //Starts an infinite loop
    P1OUT=255; //Set output high
    for (i=0;i<10000;i++) {
      nop(); //runs 10,000 'no operation' instructions to create a delay
    }
    P1OUT=0; //Set output low
    for (i=0;i<10000;i++) {
      nop(); //runs 10,000 'no operation' instructions to create a delay
    }
  }
}

void I2C_send(int address, char *data, int length) {
  int k, j;

   //if (I2CDCTL & 0x20) { // checks I2C is not busy
      // j++;
   // if (j<3){ /* loop  */
   //  wait ms(50);
   // printf ("%d",j)
   //retry send
   //}else{
   // recovery();
   //}
  //}else{

    //I2CIE = I2CIE & 0x00; // all interrupts off
    I2CIE = I2CIE & 0xB6; // interrupt flags set
    I2CTCTL = I2CTCTL | 0x28; // sets clock to SMCLK and sets to transmit

    if (I2CIFG>0) {//check transmit ready flag same function as above for busy
      U0CTL=0x37; // pg 15-21 of slau49,  listen off
      I2COA=0x01; //Sets address of MCU on the bus to 1
      I2CSA=address; //Sets address of I2C slave target(passed to function via address variable)
      I2CTCTL= I2CTCTL | 0x01; //Sends a start byte to the bus
      //printf("\n\n%x %x %x %x \n", U0CTL, I2COA, I2CSA, I2CTCTL);
      //waitms(10); // give ttc node time to respond
     /* if (I2CIFG & 0x02) {// check register for NACKIFG
          //printf("no ack")
          //square();//square wave output indicates error in send caused by flags
    }else{
      */ //interrupts currently off
      for ( k=0; k<(length); k++) {
        I2CDRB = data[k]; //Sends command number of bytes of data depends upon length parameter
        //printf (" %x\n", I2CDRB);
        //waitms(10)
        //if (I2CIFG & 0x02) {// check register for NACKIFG
        //printf("no ack")
        //square();//square wave output indicates error in send caused by flags
        //}
      }
      I2CTCTL = I2CTCTL | 0x02 ; //p 15-22 of slau49 Sends a stop condition
      //printf("%x\n --------------------------------- \n", I2CTCTL);
      //j = 0
      //waitms(10); //check wait time between signals
    }else{
    //square();
    // k++;
    //if (k<3){ /* loop  */
    //  wait ms(50);
    //  printf ("%d",k)
        //retry send
    //}else{
    //  recovery();
    //}
    }
}

int I2C_read(int address) {
  int high, low, dat;

  I2CTCTL = I2CTCTL | 0x20; // sets clock to SMCLK
  I2CTCTL = I2CTCTL & 0xF7; // sets receive mode

  U0CTL=0x3F; // pg 15-21 of slau49, listen on
  I2COA=0x1; //Sets address of MCU on the bus to 1
  I2CSA=address; //Sets address of I2C slave target

  //printf("\n %x %x %x \n", U0CTL, I2COA, I2CSA);
  low= I2CDRB;//read low (first byte sent to register
  //printf("\nPlease Enter a Hex number\n");
  //scanf("%x", &low);
  //waitms(10)
  high = I2CDRB;//read high bit
  //printf("\nPlease Enter a Hex number\n");
  //scanf("%x", &high);

  dat = (low+(high << 8));
  //printf("%x", dat);
  return dat;
}

int i2ctest(){
  /* Parameters should not be above I = 20mA and V = 3.3 V*/

int address, i, j, volt[6], curr[6], length;
int I2Cdata;
char data[2], hexv[6]= {0x00,0x03,0x06,0x09,0x0C,0x0F}, hexi[6]= {0x01,0x04,0x07,0x0A,0x0D,0x1F};

  length = 2;
  //P3DIR =255; //alternate data and clock just in case
  //P3SEL =0;
  //printf("\n\n hexv: %x %x %x %x %x %x\n ---------------------------------\n\n",hexv[0], hexv[1],hexv[2],hexv[3],hexv[4],hexv[5]);
  //printf("\n\n hexi: %x %x %x %x %x %x\n ---------------------------------\n\n",hexi[0], hexi[1],hexi[2],hexi[3],hexi[4],hexi[5]);

  address = 0x01;//sets default address and data prefix
  data[0] = 0x00;

  //Get Voltage

  for (i=0; i<6; i++) {
    data[1] = hexv[i];
    I2C_send(address, data, length); //passes address, j, data and length to void
    I2Cdata=I2C_read(address);
    volt[i]= I2Cdata;
  }
  //Get Current
  //printf("\n\n Voltage: %x %x %x %x %x %x\n ---------------------------------\n\n",volt[0], volt[1],volt[2],volt[3],volt[4],volt[5]);

  for (i=0; i<6; i++){
    data[1] = hexi[i];
    I2C_send(address, data,  length);
    I2Cdata = I2C_read(address);
    curr[i] = I2Cdata;
    if ( I2CIFG & 0x02 ){
    square();
    }
  }
//  printf("\n\n Current: %x %x %x %x %x %x\n\n ---------------------------------\n\n", curr[0],curr[1],curr[2],curr[3],curr[4],curr[5]);

//Checks levels
//printf("data all received\n\n");

  for(i=0; i<6; i++){
    if (volt[i]> 0x237){
  //    printf("Voltage recovery %d\n", i);//recovery;
    }else{
      if (curr[i]> 0x3E0){
    //    printf("Current recovery %d\n", i);//recovery;
      }
    }
  }

    P1OUT=0x00;
    P1DIR=255;    //temp code to output data from board using port 5 h1.1-8
    P1SEL=0;
    for (i=0; i<6; i++){
      P1OUT = hexv[i];
      waitms(100);
      P1OUT = hexi[i];
      waitms(100);
      //P5OUT = volt[i];
      //P5OUT= curr[i];
    }
  }

/* need to write data to SD
also need to source from clock in I2CTCTL...possibly already done
r/w needs to be set as well...set automatically see pg 15-22
sort recieve and transmit ready - must not get stuck in infinite loop - run through while loop with a set number of iterations
*/
